<template>
  <div>
    <el-card class="card">
      <template #header v-if="subjectName">
        <el-breadcrumb separator="/">
          <el-breadcrumb-item>学科管理</el-breadcrumb-item>
          <el-breadcrumb-item>{{ subjectName }}</el-breadcrumb-item>
          <el-breadcrumb-item>标签管理</el-breadcrumb-item>
        </el-breadcrumb>
      </template>

      <el-row type="flex" align="middle">
        <el-col :span="16">
          标签名称
          <el-input
            v-model="tagSearchKeyword"
            style="width: 20%; margin-right: 20px; margin-left: 5px"
          />
          状态
          <el-select
            v-model="tagSearchState"
            style="width: 20%; margin-right: 10px; margin-left: 5px"
          >
            <el-option label="启用" :value="1"></el-option>
            <el-option label="禁用" :value="0"></el-option>
          </el-select>
          <el-button size="small" @click="handleFilterClear">清除</el-button>
          <el-button type="primary" size="small" @click="page.page=1;handleSearch()">
            搜索
          </el-button>
        </el-col>
        <el-col :span="8" class="right-most-container">
          <el-button
            type="text"
            icon="el-icon-back"
            v-if="subjectName"
            @click="$router.push('/subjects/list')"
            >返回学科</el-button
          >
          <el-button
            icon="el-icon-edit"
            type="success"
            size="small"
            @click="
              editMode = false;
              addPopupVisible = true;
            "
            >新增标签</el-button
          >
        </el-col>
      </el-row>
      <el-alert
        :title="`数据一共${totalInfoCount}条`"
        type="info"
        show-icon
        class="alert"
        :closable="false"
      >
      </el-alert>
      <el-table :data="tagList"  style="width: 100%">
        <el-table-column type="index" label="序号" align="center"></el-table-column>
        <el-table-column prop="subjectName" label="所属学科" align="center"></el-table-column>
        <el-table-column prop="tagName" label="标签名称" align="center"></el-table-column>
        <el-table-column prop="username" label="创建者" align="center"></el-table-column>
        <el-table-column label="创建日期" align="center">
          <template v-slot="{ row }">
            {{ row.addDate.slice(0, 10) }} {{ row.addDate.slice(11, 19) }}
          </template>
        </el-table-column>
        <el-table-column label="状态" align="center">
          <template v-slot="{ row }">
            {{ row.state ? "已启用" : "已禁用" }}
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template v-slot="{ row }">
            <el-button
              type="text"
              @click="handleStateChange(row.id, row.state)"
              >{{ row.state ? "禁用" : "启用" }}</el-button
            >
            <el-button
              type="text"
              :disabled="!!row.state"
              @click="handleTagEdit(row.id, row.subjectID, row.tagName)"
              >修改</el-button
            >
            <el-button
              type="text"
              :disabled="!!row.state"
              @click="handleTagDeletion(row.id)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <el-row class="pagination">
        <el-pagination
          background
          layout="prev, pager, next, sizes, jumper"
          :page-sizes="[5, 10, 20, 50]"
          :total="totalInfoCount"
          :page-size="page.pagesize"
          :current-page.sync="page.page"
          @current-change="handlePageChange"
          @size-change="handlePageSizeChange"
          v-if="totalInfoCount > page.pagesize"
        >
        </el-pagination>
      </el-row>
    </el-card>

    <el-dialog
      :visible.sync="addPopupVisible"
      :title="`${editMode ? '修改' : '新增'}标签`"
      width="450px"
      @close="clearAddTagForm"
    >
      <el-form :rules="rules" :model="addTagForm" ref="addTagForm">
        <el-form-item
          label="所属学科"
          prop="subjectID"
          v-if="!this.subjectName"
        >
          <el-select v-model="addTagForm.subjectID" style="width: 79%">
            <el-option
              v-for="item in subjectList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="标签名称" prop="tagName">
          <el-col :span="19">
            <el-input placeholder="请输入标签名称" v-model="addTagForm.tagName">
            </el-input>
          </el-col>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="footer">
          <el-button @click="addPopupVisible = false">取消</el-button>
          <el-button type="primary" @click="submitAddTagForm">确认</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import {
  list as getTagList,
  add as addTag,
  changeState as changeTagState,
  remove as removeTag,
  update as updateTag
} from '@/api/hmmm/tags'
import { simple as getSubjectList } from '@/api/hmmm/subjects'
export default {
  async created () {
    // 如果是从学科跳转而来，以后的刷新页面请求都要加上学科id
    // 在初始化时就把学科id存起来，以后发送请求时不需要手动写学科id
    if (this.subjectName) {
      this.page.subjectID = this.currentId
      this.addTagForm.subjectID = this.currentId
    }
    // 创建页面时同时请求页面数据和弹窗里下拉选单中的数据
    this.loadCurrentPage()
    this.loadSubjectList()
  },
  data () {
    return {
      // 正在被编辑的标签的id，如果是跳转而来的最开始会借用此变量储存学科id
      currentId: Number(this.$route.query.id),
      // 从哪个学科跳转过来的
      subjectName: this.$route.query.name,
      editMode: false,
      // 弹窗里的表单
      addTagForm: {
        subjectID: '',
        tagName: ''
      },
      // 控制弹窗的隐藏和显示
      addPopupVisible: false,
      // 以下2个变量分别对应搜索框的标签名称和状态
      tagSearchKeyword: '',
      tagSearchState: '',
      // 铺设页面用的数据（标签详情数据）
      tagList: [],
      // 铺设弹窗里下拉选单的数据（学科信息）
      subjectList: [],
      // 分页器相关，刷新页面时作为请求的参数
      page: {
        page: 1,
        pagesize: 10
      },
      // 数据总条数，从后台获取
      totalInfoCount: 0,
      // 用于弹窗里表单的校验规则
      rules: {
        tagName: [
          { required: true, message: '请输入标签名称', trigger: 'change' }
        ],
        subjectID: [
          { required: true, message: '请选择学科', trigger: 'change' }
        ]
      }
    }
  },
  computed: {
    // 判断当前是否处于搜索模式，搜索模式下请求新数据（翻页）要用handleSearch函数
    searchMode () {
      return this.tagSearchState !== '' || this.tagSearchKeyword !== ''
    }
  },
  methods: {
    // 点击修改时的回调函数。进行数据回填，并把当前标签id存放在currentId中
    handleTagEdit (id, subjectID, tagName) {
      this.editMode = true
      this.currentId = id
      this.addTagForm.subjectID = subjectID
      this.addTagForm.tagName = tagName
      this.addPopupVisible = true
    },
    // 点击删除时的回调函数，删除当前标签
    async handleTagDeletion (id) {
      try {
        await this.$confirm('此操作将永久删除该标签, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        await removeTag({ id })
        this.$message.success('删除成功')
        // 如果删除的是页面的最后一个元素，去拉取前一页的数据
        this.tagList.length === 1 && this.page.page > 1 && this.page.page--
        this.updatePage()
      } catch (err) {
        if (err !== 'cancel') this.$message.error('删除失败')
      }
    },
    // 点击启用/禁用时的回调函数，改变标签状态
    async handleStateChange (id, state) {
      try {
        await changeTagState({
          id,
          state: state ? 0 : 1
        })
        this.$message.success('操作成功')
        this.updatePage()
      } catch (err) {
        this.$message.error('操作失败')
      }
    },
    // 根据情况重置表单
    // 如果是跳转来的需要在关闭表单时保留subjectID属性，否则关闭表单清除整个addTagForm
    clearAddTagForm () {
      if (this.subjectName) {
        this.addTagForm.tagName = ''
      } else {
        this.addTagForm = {
          subjectID: '',
          tagName: ''
        }
      }
      this.$nextTick(() => {
        this.$refs.addTagForm.clearValidate()
      })
    },
    // 提交弹窗表单的回调函数，新增标签
    submitAddTagForm () {
      this.$refs.addTagForm.validate(async (valid) => {
        if (valid) {
          if (!this.editMode) {
            try {
              await addTag(this.addTagForm)
              this.$message.success('添加标签成功')
              // 标签添加成功后，先清空搜索框，再重新拉取第一页数据，目的是让用户看到新增的数据，防止用户懵逼
              this.handleFilterClear()
              this.page.page = 1
              this.loadCurrentPage()
              this.addPopupVisible = false
            } catch (err) {
              this.$message.error('添加标签失败')
            }
          } else {
            try {
              // 进行标签编辑时，需要额外添加当前修改的标签的id发送给后端
              await updateTag({ ...this.addTagForm, id: this.currentId })
              this.$message.success('修改标签成功')
              this.updatePage()
              this.addPopupVisible = false
            } catch (err) {
              this.$message.error('修改标签失败')
            }
          }
        } else {
          this.$message.error('请填写所有必填项后重试')
          return false
        }
      })
    },
    // 获取弹窗的学科下拉选单中的数据
    async loadSubjectList () {
      this.subjectList = (await getSubjectList()).data
    },
    // 根据页码请求当前页数据
    async loadCurrentPage () {
      const res = await getTagList(this.page)
      this.tagList = res.data.items
      this.totalInfoCount = res.data.counts
    },
    // 拉取页面数据时根据搜索框决定是拉取全部页面数据还是搜索数据
    updatePage () {
      this.searchMode ? this.handleSearch() : this.loadCurrentPage()
    },
    // 以下是分页器相关的2个函数，发生变化就要重新拉取页面数据
    handlePageChange (current) {
      this.page.page = current
      this.updatePage()
    },
    handlePageSizeChange (current) {
      this.page.pagesize = current
      this.page.page = 1
      this.updatePage()
    },
    // 搜索的回调函数，点击搜索时会执行，当搜索框不为空时所有刷新页面有关的操作也会执行它
    async handleSearch () {
      const newObj = { ...this.page }
      this.tagSearchKeyword !== '' && (newObj.tagName = this.tagSearchKeyword)
      this.tagSearchState !== '' && (newObj.state = this.tagSearchState)
      const res = await getTagList(newObj)
      this.tagList = res.data.items
      this.totalInfoCount = res.data.counts
    },
    // 清空搜索条件时的回调函数
    handleFilterClear () {
      this.tagSearchKeyword = ''
      this.tagSearchState = ''
    }
  }
}
</script>

<style scoped>
.footer {
  text-align: right;
}
.pagination {
  padding-top: 20px;
  text-align: right;
}
.card {
  margin: 10px;
}
.label {
  font-size: 15px;
  text-align: right;
  padding-right: 10px;
}

.btn-container {
  padding-left: 20px;
}

.right-most-container {
  text-align: right;
}

.alert {
  margin: 20px 0;
}
</style>
